import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import deviceUnoList from "./unoList";
import { skyBox } from "./createEnvBox";

var originCabinet = null;
const envTexture = skyBox();
export const createCabinets = async (roomSize, cabinetList) => {
  if (!originCabinet) {
    originCabinet = await loadCabinetModule();
  }
  const cabinets = arrangeCabinet(roomSize, cabinetList);
  return cabinets;
};

// 加载GLTF模型(机柜模型x:0.6,y:2,z:0.93)
const loadCabinetModule = () => {
  return new Promise((resolve) => {
    const loader = new GLTFLoader();
    loader.load(`./models/cabinet/cabinet.gltf`, (val) => {
      resolve(val.scene.children[0]);
    });
  });
};

//排列机柜
const arrangeCabinet = (roomSize, cabinetList) => {
  const cabinets = [];
  cabinetList.forEach((item, index) => {
    let cabinet = originCabinet.clone();
    cabinet.position.set(item[0] - 0.5 - roomSize.width / 2, 0, item[1] - 0.5 - roomSize.height / 2);
    cabinet.userData = {
      name: `机柜${index + 1}`
    };
    // const edges = new THREE.EdgesGeometry(cabinet.geometry);
    // const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0x409eff }));
    // cabinet.add(line);
    cabinets.push(cabinet);
    // cabinet.material.transparent = true;
    // cabinet.material.opacity = 0.3;
  });
  return cabinets;
};

//创建机柜盒子
export const createCabinetBox = (uNum) => {
  let boxgroup = new THREE.Group();
  let material = new THREE.MeshStandardMaterial({
    color: "#333333", // 基础颜色
    metalness: 1.0, // 金属度（0-1）
    roughness: 0.3, // 粗糙度（0-1）
    envMap: envTexture,
    envMapIntensity: 1 // 环境映射强度
  });

  const width = 5,
    uHeight = 0.47,
    depth = 4,
    thickness = 0.2;
  const height = (uHeight + 0.01) * uNum + thickness * 2;

  const bottom = new THREE.Mesh(new THREE.BoxGeometry(width, thickness, depth), material); //底面
  bottom.position.set(0, thickness / 2, 0);
  const right = new THREE.Mesh(new THREE.BoxGeometry(thickness, height, depth), material); //底面
  right.position.set((width + thickness) / 2, height / 2, 0);
  const left = new THREE.Mesh(new THREE.BoxGeometry(thickness, height, depth), material); //底面
  left.position.set(-(width + thickness) / 2, height / 2, 0);
  const top = new THREE.Mesh(new THREE.BoxGeometry(width, thickness, depth), material); //底面
  top.position.set(0, height - thickness / 2, 0);
  const back = new THREE.Mesh(new THREE.BoxGeometry(width + thickness * 2, height, thickness), material); //底面
  back.position.set(0, height / 2, -depth / 2);
  boxgroup.add(...[bottom, right, left, top, back]);

  const deviceList = createDevice();
  boxgroup.add(...deviceList);
  return { boxgroup, deviceList };
};

const createDevice = () => {
  const deviceList = [];
  const width = 5,
    uHeight = 0.47,
    depth = 4;
  let y = 0.2;
  const loader = new THREE.TextureLoader();

  let newDeviceList = handleRackUno(deviceUnoList, 1);
  let baseMaterial = new THREE.MeshStandardMaterial({
    color: "#333333",
    metalness: 1, // 金属度（0-1）
    roughness: 0.5, // 粗糙度（0-1）
    envMap: envTexture
  });
  newDeviceList.forEach((item) => {
    let material = "",
      uNum = 1;
    let device = null;
    if (item.deviceInfo) {
      material = [
        baseMaterial,
        baseMaterial,
        baseMaterial,
        baseMaterial,
        new THREE.MeshBasicMaterial({
          map: loader.load("http://47.113.185.182:7374" + item.deviceInfo.imageUrl)
          // transparent: true,
          // opacity: 0.8
        }),
        baseMaterial
      ];
      uNum = item.deviceInfo.unoIndexList.length;
      device = new THREE.Mesh(new THREE.BoxGeometry(width, uHeight * uNum, depth), material);
      device.position.y = y + (uHeight * uNum) / 2;
      device.userData = item.deviceInfo ? item.deviceInfo : {};
      deviceList.push(device);
    }
    y += uHeight * uNum + 0.01;
  });
  return deviceList;
};

//处理设备占用多U位的情况
const handleRackUno = (rackUnoList, sort) => {
  let newList = [];
  for (let i = 0, len = rackUnoList.length; i < len; i++) {
    //判断是否反序
    if (sort == 2 && rackUnoList[i].deviceInfo) {
      rackUnoList[i].deviceInfo.unoIndexList = rackUnoList[i].deviceInfo.unoIndexList.reverse();
    }
    if (i == 0 || !rackUnoList[i].deviceInfo) {
      newList.push(rackUnoList[i]);
    } else {
      let curUno = rackUnoList[i].deviceInfo;
      let preUno = rackUnoList[i - 1].deviceInfo;

      if (!preUno || curUno.id != preUno.id || curUno.deviceType != preUno.deviceType) {
        newList.push(rackUnoList[i]);
      }
    }
  }
  return newList;
};
